
#ifndef CONTACT_H_
#define CONTACT_H_

#include "Core.h"
#include "Entity.h"

namespace p2 {

class Contact
{
public:
	typedef std::list<Contact, boost::fast_pool_allocator<Contact> > List;

public:
	inline Contact(Element* A, Element* B, Vector2<real> (&pa)[2],
		Vector2<real> (&pb)[2], Vector2<real> n);
	inline Contact(Element* A, Element* B, Vector2<real> pa, Vector2<real> pb,
		Vector2<real> n);

	void applyImpulses(Vector2<real> impulse, uint32 pi);

private:
	inline Contact& operator= (Contact const& val)
	{
		if (this != &val) {
		}
		return *this;
	}
	void initialise(Vector2<real>& pa, Vector2<real>& pb, uint32 pi);

public:
	Element* _a;
	Element* _b;
	uint32 const _nppb;
	Vector2<real> const _normal;
	Vector2<real> _pa[2];
	Vector2<real> _pb[2];
	Vector2<real> _ra[2];
	Vector2<real> _rb[2];
	Vector2<real> _dv[2];
	real _impulseN[2];
	real _impulseT[2];
	real _dist[2];
	real _invDenom[2];
	real _invDenomTan[2];
	///*
	// * REF: http://i31www.ira.uka.de/docs/PaperFinal.pdf
	// * 'The impact law of Newton .. states that the relative velocity
	// * of a pair of contact points in the direction of the normal after a collision is
	// * ucreln = -e . ureln
	// */
	//real _cor;
	//real _muK, _muS;
	//real _ucreln[2];
	//real _accPn, _accPtK, _accPtS;
};

inline Contact::Contact(Element* a, Element* b, Vector2<real> (&pa)[2],
	Vector2<real> (&pb)[2], Vector2<real> n)
	: _a(a), _b(b), _nppb(2), _normal(n)
{
	for (uint32 pi = 0; pi < _nppb; ++pi) {
		initialise(pa[pi], pb[pi], pi);
	}
}

inline Contact::Contact(Element* a, Element* b, Vector2<real> pa,
	Vector2<real> pb, Vector2<real> n)
	: _a(a), _b(b), _nppb(1), _normal(n)
{
	initialise(pa, pb, 0);
}

}

#endif	//CONTACT_H_
